Problem 2 (Image denoising with average and Gaussian filters).¶

(a) Write a function awgn that takes in an input image and noise-level and adds i.i.d2 zero-mean Gaussian random noise with standard-deviation.¶

In [8]:
def awgn(img,sigma):
    img1 = img + sigma*np.random.randn(np.shape(img)[0],np.shape(img)[1])
    img2 = (img1-np.amin(img1))*1/(np.amax(img1)-np.amin(img1))
    return img2

(b) Write a function gaussian_filter which returns a 2D Gaussian filter of size m x m.¶

In [9]:
def gaussian_filter(m,sigma):
    x = np.arange(-(m-1)/2,(m+1)/2)
    gauss = np.exp(-x**2/(2*sigma**2))
    gauss2 = np.empty((m,m))
    for i in range(m):
        for j in range(m):
            gauss2[i][j] = gauss[i]*gauss[j]
    return gauss2/np.sum(gauss2)

(c) Generate a noisy version of an image using awgn, with a noise-level an = 0:1 on an image intensity scale of [0, 1]. Apply separately a Gaussian filter of size 5 x 5 and average-filter of size 5 x 5, and comment on how the filters compare in their noise-removal, qualitatively. Repeat this for a few different noise-levels and filter sizes. Each time, calculate the PSNR3 of your noisy and denoised images¶

In [10]:
def psnr(img1,img2):
    mse = ((img1-img2)**2).mean()
    return -10*np.log10(mse)

Generating a noisy version of an image with noise-level = 0.1, and a 5x5 filter¶

In [11]:
img = cv2.imread('lena_gray.bmp',0)
img = img/255 #Normalizing the image down to an intensity of [0,1]

img_noisy1 = awgn(img,0.1)
filt_gauss_5x5 = gaussian_filter(5,1)
filt_avg_5x5 = 1/25*np.ones((5,5))

plt.figure(figsize = (15,15))
plt.subplot(2,2,1)
plt.imshow(img,cmap='gray')
plt.title('original image')
plt.axis('off')
plt.subplot(2,2,2)
plt.imshow(img_noisy1,cmap='gray')
plt.title('noisy image, σ = 0.1, PSNR = '+str(psnr(img,img_noisy1)))
plt.axis('off')
plt.subplot(2,2,3)
img_gauss = conv2(img_noisy1,filt_gauss_5x5)
plt.imshow(img_gauss,cmap='gray')
plt.title('5x5 gaussian filter ~N(0,1) PSNR = '+str(psnr(img,img_gauss)))
plt.axis('off')
plt.axis('off')
plt.subplot(2,2,4)
img_avg = conv2(img_noisy1,filt_avg_5x5)
plt.imshow(img_avg,cmap='gray')
plt.title('5x5 average filter, PSNR = '+str(psnr(img,img_avg)))
plt.axis('off')
plt.axis('off')
Out[11]:
(-0.5, 511.5, 511.5, -0.5)

Image becomes noisy and then denoises and becomes blurry.

show_image function¶

Different Noise Levels¶

In [12]:
noise_levels = [0.1, 0.2, 0.5, 1, 10]
plt.figure(figsize = (15,15))
plt.subplot(3,2,1)
plt.imshow(img,cmap='gray')
plt.title('original image')
plt.axis('off')
s = 2
for n in noise_levels:
    img_noisy = awgn(img,n)
    plt.subplot(3,2,s)
    plt.imshow(img_noisy,cmap='gray')
    plt.title('noisy image, σ = '+str(n)+', PSNR = '+str(psnr(img,img_noisy)))
    plt.axis('off')
    s += 1

Different Gauss Filters Sizes¶

In [13]:
filer_sizes = [3, 5, 9, 15]
plt.figure(figsize = (15,15))
plt.subplot(3,2,1)
plt.imshow(img,cmap='gray')
plt.title('original image')
plt.axis('off')
img_noisy = awgn(img,0.2)
plt.subplot(3,2,2)
plt.imshow(img_noisy,cmap='gray')
plt.title('noisy image, σ = '+str(0.2)+', PSNR = '+str(psnr(img,img_noisy)))
plt.axis('off')
s = 3
for f in filer_sizes:
    filt = gaussian_filter(f,1)
    img_gauss = conv2(img_noisy,filt)
    plt.subplot(3,2,s)
    plt.imshow(img_gauss,cmap='gray')
    plt.title(str(f)+'x'+str(f)+ ' gaussian filter PSNR = '+str(psnr(img,img_gauss)))
    plt.axis('off')
    s += 1

Different Average Filters Sizes¶

In [14]:
plt.figure(figsize = (15,15))
plt.subplot(3,2,1)
plt.imshow(img,cmap='gray')
plt.title('original image')
plt.axis('off')
img_noisy = awgn(img,0.2)
plt.subplot(3,2,2)
plt.imshow(img_noisy,cmap='gray')
plt.title('noisy image, σ = '+str(0.2)+', PSNR = '+str(psnr(img,img_noisy)))
plt.axis('off')
s = 3
for f in filer_sizes:
    filt = filt = (1/f**2)*(np.ones([f,f]))
    img_avg = conv2(img_noisy,filt)
    plt.subplot(3,2,s)
    plt.imshow(img_avg,cmap='gray')
    plt.title(str(f)+'x'+str(f)+ ' average filter PSNR = '+str(psnr(img,img_avg)))
    plt.axis('off')
    s += 1

As the filter size increases, filter becomes better at removing noise but also, the image gets a lot blurrier.